package logic

import (
	"book/internal/pb"
	"book/internal/types"
	"common"
	"common/logic"
	"common/zapx"
	"context"
	"errors"
	"go.uber.org/zap"
	"gorm.io/gorm"
	"models/dal/model"
	"models/dal/query"
	"strings"
	"time"
)

type BookLogic struct {
	*logic.BasePageLogic
}

// NewBookLogic 新建book logic
func NewBookLogic() *BookLogic {
	logic := &BookLogic{
		BasePageLogic: &logic.BasePageLogic{
			Page:     0,
			PerPage:  15,
			NextPage: 0,
			Total:    0,
		},
	}

	return logic
}

// Favourite 收藏漫画逻辑
func (bl *BookLogic) Favourite(ctx context.Context, comicId int32) (operate int32, err error) {
	timeoutCtx, cancel := common.WithTimeoutContext(time.Second * 2)
	defer cancel()
	comicModel := query.Q.FaComic.WithContext(timeoutCtx)
	_, err = comicModel.Where(query.Q.FaComic.ID.Eq(comicId)).First()
	if err != nil {
		return 0, errors.New("漫画不存在")
	}
	user, err := common.GetUserByGrpc(ctx)
	if err != nil {
		return 0, err
	}
	//查询是否收藏
	bookModel := query.Q.FaBook.WithContext(timeoutCtx)
	book, e := bookModel.Where(query.Q.FaBook.UserID.Eq(user.ID)).Where(query.Q.FaBook.ComicID.Eq(comicId)).First()
	if errors.Is(e, gorm.ErrRecordNotFound) {
		//没有收藏
		err := bookModel.Create(&model.FaBook{
			UserID:  user.ID,
			ComicID: comicId,
		})
		if err != nil {
			zapx.Logger.Error("插入数据失败", zap.Error(err))
		}
		operate = 2
	} else {
		//收藏了
		_, err := query.Q.FaBook.WithContext(ctx).Delete(book)
		if err != nil {
			zapx.Logger.Error("删除数据失败", zap.Error(err))
		}
		operate = 1
	}
	return
}

// List 收藏列表
func (bl *BookLogic) List(grpcCtx context.Context) (ret []*pb.ComicEntity) {
	ret = make([]*pb.ComicEntity, 0)
	user, err := common.GetUserByGrpc(grpcCtx)
	if err != nil {
		return ret
	}
	ctx, cancel := common.WithTimeoutContext(time.Second * 2)
	defer cancel()
	bookModel := query.Q.FaBook.WithContext(ctx)
	var entity []types.ListEntity
	total, _ := bookModel.Select(query.Q.FaComic.ALL).
		Join(query.Q.FaComic, query.Q.FaComic.ID.EqCol(query.Q.FaBook.ComicID)).
		Where(query.Q.FaBook.UserID.Eq(user.ID)).
		ScanByPage(&entity, bl.GetOffset(), int(bl.GetPerPage()))

	bl.BasePageLogic.SetTotal(total)

	for _, comicEntity := range entity {
		ret = append(ret, &pb.ComicEntity{
			Id:     comicEntity.Id,
			Title:  comicEntity.Title,
			Thumb:  common.ParseUri(comicEntity.Thumb),
			Swiper: make([]string, 0),
			Author: comicEntity.Author,
			Intro:  comicEntity.Intro,
			Tags:   strings.Split(comicEntity.Tags, ","),
		})
	}
	return ret
}

// IsFavourite 是否收藏
func (bl *BookLogic) IsFavourite(grpcCtx context.Context, comicId int32) (int32, error) {
	user, err := common.GetUserByGrpc(grpcCtx)
	if err != nil {
		return 0, err
	}
	//查询是否收藏了漫画
	ctx, cancel := common.WithTimeoutContext(time.Second * 2)
	defer cancel()
	bookModel := query.Q.FaBook.WithContext(ctx)
	cnt, err := bookModel.Where(query.Q.FaBook.ComicID.Eq(comicId)).Where(query.Q.FaBook.UserID.Eq(user.ID)).Count()
	if err != nil {
		return 0, nil
	}
	return int32(cnt), nil
}
